package com.youlu.campus.service.ca.impl;

import com.alibaba.fastjson.JSON;
import com.mongodb.client.result.DeleteResult;
import com.mongodb.client.result.UpdateResult;
import com.youlu.campus.base.exception.BusinessException;
import com.youlu.campus.entity.*;
import com.youlu.campus.entity.VO.req.SingleOrderConfigQueryVO;
import com.youlu.campus.service.activity.ActivityService;
import com.youlu.campus.service.ca.CaMaterialConfigService;
import com.youlu.campus.service.ca.SingleOrderConfigService;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Sort;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.data.mongodb.core.query.Update;
import org.springframework.data.repository.support.PageableExecutionUtils;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Objects;

@Slf4j
@Service
public class SingleOrderConfigServiceImpl implements SingleOrderConfigService {
    @Autowired
    private MongoTemplate mongoTemplate;
    @Autowired
    private ActivityService activityService;
    @Autowired
    private CaMaterialConfigService caMaterialConfigService;

    @Override
    public Page<SingleOrderConfig> list(SingleOrderConfigQueryVO req) {
        log.info(":>>> 开始获取合单提示语:{}", JSON.toJSON(req));
        if (Objects.isNull(req)) {
            log.error(":>>> 获取订单材质配置为空");
            throw new BusinessException("订单材质配置参数错误");
        }
        Query query = new Query();
        if (StringUtils.isNotBlank(req.getActivityId())) {
            query.addCriteria(Criteria.where("activityId").is(req.getActivityId()));
        }
        query.addCriteria(Criteria.where("deleted").ne(true));
        long count = mongoTemplate.count(query, SingleOrderConfig.class);
        PageRequest pageRequest = PageRequest.of(req.getPage() - 1, req.getPageSize());
//        query.with(new Sort(Sort.Direction.DESC, "createdTime"));
        Sort sort=Sort.by(Sort.Direction.DESC, "createdTime");
        query.with(sort);
        List<SingleOrderConfig> infos = mongoTemplate.find(query.with(pageRequest), SingleOrderConfig.class);
        return PageableExecutionUtils.getPage(infos, pageRequest, () -> count);
    }

    @Override
    public boolean create(SingleOrderConfig req) {
        log.info(":>>> 开始创建合单规则列表:{}", JSON.toJSONString(req));
        if (Objects.isNull(req) || StringUtils.isBlank(req.getActivityId()) || CollectionUtils.isEmpty(req.getDetails())) {
            log.error(":>>> 创建合单规则参数错误");
            throw new BusinessException("创建合单规则参数错误");
        }
        Date date = new Date();
        ActivityInfo activityInfo = activityService.findOne(req.getActivityId());
        if (Objects.nonNull(activityInfo)) {
            req.setActivityName(activityInfo.getName());
        }
        req.setId(null);
        req.setCreatedTime(date);
        for (SingleOrderConfigDetail detail : req.getDetails()) {
            if (StringUtils.isBlank(detail.getCaMaterialConfigId())) {
                throw new BusinessException("合单规则参数参数错误");
            }

        }
        req = mongoTemplate.insert(req);
        String value = "";
        for (SingleOrderConfigDetail detail : req.getDetails()) {
            detail.setSingleOrderConfigId(req.getId());
            CaMaterialConfig config = caMaterialConfigService.findOne(detail.getCaMaterialConfigId());
            if (Objects.nonNull(config)) {
                detail.setCaMaterialConfigName(config.getName());
                if (StringUtils.isBlank(value)) {
                    value = config.getName();
                } else {
                    value = value + "+" + config.getName();
                }
            }
            detail.setCreatedTime(date);
            detail.setActivityId(activityInfo.getId());
            detail.setActivityName(activityInfo.getName());
            mongoTemplate.insert(detail);
        }
        Query query2 = new Query().addCriteria(Criteria.where("id").is(req.getId()));
        Update update = new Update();
        update.set("value", value);
        mongoTemplate.updateFirst(query2, update, SingleOrderConfig.class);
        return true;
    }

    @Override
    public boolean update(SingleOrderConfig req) {
        log.info(":>>> 开始修改合单规则列表:{}", JSON.toJSONString(req));
        if (Objects.isNull(req) || StringUtils.isBlank(req.getId()) || CollectionUtils.isEmpty(req.getDetails())) {
            log.error(":>>> 修改合单规则参数错误");
            throw new BusinessException("修改合单规则参数错误");
        }
        SingleOrderConfig exist = this.findOne(req.getId());
        Date date = new Date();
        Query queryRemoveDetail = new Query().addCriteria(Criteria.where("singleOrderConfigId").is(req.getId()));
        DeleteResult deleteResult = mongoTemplate.remove(queryRemoveDetail, SingleOrderConfigDetail.class);
        for (SingleOrderConfigDetail detail : req.getDetails()) {
            if (StringUtils.isBlank(detail.getCaMaterialConfigId())) {
                throw new BusinessException("合单规则参数参数错误");
            }

        }
        String value = "";
        for (SingleOrderConfigDetail detail : req.getDetails()) {
            detail.setSingleOrderConfigId(req.getId());
            CaMaterialConfig config = caMaterialConfigService.findOne(detail.getCaMaterialConfigId());
            if (Objects.nonNull(config)) {
                detail.setCaMaterialConfigName(config.getName());
                if (StringUtils.isBlank(value)) {
                    value = config.getName();
                } else {
                    value = value + "+" + config.getName();
                }
            }
            detail.setCreatedTime(date);
            detail.setActivityId(exist.getActivityId());
            mongoTemplate.insert(detail);
        }
        Query query2 = new Query().addCriteria(Criteria.where("id").is(req.getId()));
        Update update = new Update();
        update.set("value", value);
        mongoTemplate.updateFirst(query2, update, SingleOrderConfig.class);
        return true;
    }

    @Override
    public boolean delete(String id) {
        Query query = new Query().addCriteria(Criteria.where("id").is(id));
        Update update = new Update();
        update.set("deleted", true);
        UpdateResult updateResult = mongoTemplate.updateMulti(query, update, SingleOrderConfig.class);
        log.info(":>>> 删除合单规则:{} 结果:{}", id, updateResult.getModifiedCount() > 0 ? true : false);
        return updateResult.getModifiedCount() > 0 ? true : false;
    }

    @Override
    public SingleOrderConfig findOne(String id) {
        Query query = new Query().addCriteria(Criteria.where("id").is(id));
        SingleOrderConfig config = mongoTemplate.findOne(query, SingleOrderConfig.class);
        List<SingleOrderConfigDetail> details = getDetail(id);
        config.setDetails(details);
        return config;
    }

    @Override
    public List<SingleOrderConfigDetail> getDetail(String singleOrderConfigId) {
        Query queryDetail = new Query().addCriteria(Criteria.where("singleOrderConfigId").is(singleOrderConfigId));
        List<SingleOrderConfigDetail> details = mongoTemplate.find(queryDetail, SingleOrderConfigDetail.class);
        return details;
    }

    @Override
    public List<String> getMatertailItemId(String singleOrderConfigId, String activityId) {
        List<String> itemIds = new ArrayList<>();
        List<SingleOrderConfigDetail> details = this.getDetail(singleOrderConfigId);
        for (SingleOrderConfigDetail s : details) {
            Query query = new Query().addCriteria(Criteria.where("activityId").is(activityId).and("materialConfigId").is(s.getCaMaterialConfigId()));
            List<CaInfo> caInfos = mongoTemplate.find(query, CaInfo.class);
            for (CaInfo caInfo : caInfos) {
                if(!itemIds.contains(caInfo.getId())){
                    itemIds.add(caInfo.getId());
                }
            }
        }
        return itemIds;
    }
}
